'''
Created on 21 nov. 2014

@author: Damien Torond et Geoffrey Sentost
Module Parking
'''
from modele import Niveau

'''
import du module Niveau depuis modele.
'''

class Parking():
    
    '''
    La classe Parking modelise un parking avec ses differents niveaux et places.
    '''

    # nbNiveaux et nbPlaces par Niveau dans le constructeur de base, nbPlacesCapacite si ca vient de la bdd
    def __init__(self, ctrlBdd, pNbNiv, pNbPlaces, pPrix, bool):
        '''
        Constructeur de la classe Parking.
        Attributs:
            - presentDansBdd de type booleen, verifie si le parking a ete cree dans la base de donnees.
            - nbPlacesCapacite de type int, capacite du parking.
            - nbPlacesParNiv de type int, capacite de places par niveaux.
            - nbNiv de type int, nombre de niveau dans le parking.
            - listeNiveaux de type list, liste des niveaux.
            - listeAbo de type list, liste des abonnements.
            - nbAcces de type int initialise a 2, nombre d'acces au parking.
            - prixPlace de type int, prix de la place.
            - bdd instance de CtrlBdd.
        '''
        self.presentDansBdd = bool
        if self.presentDansBdd :
            self.nbPlacesCapacite = pNbPlaces
            self.nbPlacesParNiv = pNbPlaces / pNbNiv
        else :
            self.nbPlacesCapacite = pNbPlaces*pNbNiv
            self.nbPlacesParNiv = pNbPlaces
          
        self.bdd = ctrlBdd
        
        self.nbPlacesLibres = self.nbPlacesCapacite
        self.nbNiv = pNbNiv
        self.listeNiveaux = []
        self.listeAbo = []
        self.nbAcces = 2
        self.prixPlace = pPrix
    
    
    def getPlace(self, numNiv, numPlace):
        '''
        Methode : attend un numero de niveau et de place en parametre.
        Permet de recuperer une place specifique et retourne donc une place.
        '''
        for place in self.listeNiveaux[numNiv].getListePlaces():
            if place.getNumPlace() == numPlace :
                return place      
   
     
    def remplirListeNiveaux(self):
        '''
        Methode : On incremente un compteur afin de pouvoir ajouter un niveau en plus (nombre de niveaux).
        '''
        cpt = 0
        while cpt < self.nbNiv:
            self.ajouterNiveau(cpt)    
            cpt = cpt+1
    
            
    def getNbNiveaux(self):
        '''
         Methode : accesseur de l'attribut nbNiv qui retourne celui-ci.
        '''
        return self.nbNiv
    
        
    def getNbPlacesLibres(self):
        '''
         Methode : accesseur de l'attribut nbPlacesLibres qui retourne celui-ci.
        '''
        return self.nbPlacesLibres
    
    
    def getNbPlacesCapacite(self):
        '''
         Methode : accesseur de l'attribut nbPlacesCapacite qui retourne celui-ci.
        '''
        return self.nbPlacesCapacite
    
    
    def ajouterNiveau(self, num):
        '''
        Methode : attend un numero en parametre.
        Permet d'ajouter un niveau au parking, un numero et un nombre de places.
        On ajoute le niveau a la liste listeNiveaux.
        '''
        if self.presentDansBdd == True :
            niveau = Niveau.Niveau(self, num, self.nbPlacesParNiv, self.bdd.renseignerListePlaces(num))
        else :
            niveau = Niveau.Niveau(self, num, self.nbPlacesParNiv)
            self.bdd.ajouterNiveau(niveau)
        
        self.listeNiveaux.append(niveau)    
            
    
    def estPlein(self):
        '''
        Methode: on verifie si le parking est plein (places libres inferieurs a 0).
        '''
        return (self.nbPlacesLibres <= 0)
    
    
    def getNbAcces(self):
        '''
         Methode : accesseur de l'attribut nbAcces qui retourne celui-ci.
        '''
        return self.nbAcces
    
        
    def incrementer(self):             
        '''
        Methode:permet d'incrementer le nombre de places libres.
        '''
        if self.nbPlacesLibres <= self.nbPlacesCapacite :
            self.nbPlacesLibres = self.nbPlacesLibres+1
        else :
            print("Impossible parking vide")
   
     
    def decrementer(self):
        '''
        Methode:permet de decrementer le nombre de places libres.
        '''
        if self.nbPlacesLibres > 0 :
            self.nbPlacesLibres = self.nbPlacesLibres-1
        else :
            print("Impossible parking plein") 

    
    def placementTrouve(self, voiture, bdd):
        '''
        Methode: attend une instance de la classe Voiture et de CtrlBdd.
        Verifie si la un placement a ete trouve pour une voiture, en verifiant si le client est superAbonne
        (la place sera trouve directement car placement permanent).
        On cherche alors la place ideale pour la voiture.
        '''
        client = voiture.getProprietaire()
        if client.getEstSuperAbonne() and not client.getDevenirSuperAbo() :
            trouve = True
        else :
            infos = bdd.getInfosPlaceIdeale(voiture)
            trouve = False
            if infos :
                trouve = True
        
        return trouve
    
    
    def peutEtrePlacee(self, voiture, bdd):
        '''
        Methode: attend une instance de la classe Voiture et de CtrlBdd.
        Verifie si la voiture peut etre placee ou non, en fonction que le parking est plein ou non.
        '''
        return (self.placementTrouve(voiture, bdd) and not self.estPlein() and not voiture.getEstGaree())
    
    
    '''
    #algo qui place la voiture selon les dimensions de la place, prio aux places de plus bas niveau et de plus bas numéro de place
    def addPlacement(self, voiture, imageVoiture):
        cptNiveaux = 0
        cptPlaces = 0
        sortie = False
        
        while cptNiveaux < self.nbNiv and sortie == False :
            niveau = self.listeNiveaux[cptNiveaux]
            
            if niveau.estPlein() == False :
                listePlacesNiveau = niveau.getListePlaces()
                while cptPlaces < niveau.getNbPlacesLibresNiveau() and listePlacesNiveau[cptPlaces].getPeutEtreGaree(imageVoiture) == False :
                    cptPlaces = cptPlaces+1
                    
                if cptPlaces != niveau.getNbPlacesLibresNiveau() :
                    sortie = True
                
            if sortie == False :
                cptNiveaux = cptNiveaux+1
                
        if sortie == True :
            self.listeNiveaux[cptNiveaux].getListePlaces()[cptPlaces].allouerPlace(voiture, self.bdd)
        
        return sortie
    '''
    
    def addPlacement(self, voiture, imageVoiture, bdd):
        '''
         Methode : attend une instance de la classe Voiture, imageVoiture et CtrlBdd.
         Permet d'ajouter un placement en fonction des dimensions de la voiture.
         Elle retourne 0 ou 1 en fonction qu'on est trouver une place ideale ou non.
        '''
        infos = bdd.getInfosPlaceIdeale(imageVoiture)
        trouve = 0
        if infos :
            trouve = 1
            place = self.getPlace(infos[0], infos[1])
            place.allouerPlace(voiture, bdd)
        
        return trouve

    
    def addPlacementSuperAbo(self, voiture, imageVoiture, bdd):
        '''
         Methode : attend une instance de la classe Voiture, imageVoiture et CtrlBdd.
         Permet d'ajouter un placement permanent a un superAbonne, en fonction des 
         dimensions de la voiture.
         On met a jour les informations de la place sur la base de donnees.
        '''
        infos = bdd.getInfosPlaceSuperAbo(imageVoiture)
        place = self.getPlace(infos[0], infos[1])
        place.allouerPlace(voiture, bdd)
        
    
    def sortirPlace(self, voiture, bdd):
        '''
         Methode : attend une instance de la classe Voiture et de CtrlBdd.
         Permet de sortir de la place et de la liberer.
         Met a jour la base de donnees.
        '''
        placeALib = voiture.getPlacement().getPlace()
        placeALib.libererPlace(voiture, bdd)
        
        
    def getListeAbo(self):
        '''
         Methode : accesseur de l'attribut listeAbo qui retourne celui-ci.
        '''
        return self.listeAbo
    
    
    def getPrixPlace(self):
        '''
         Methode : accesseur de l'attribut prixPlace qui retourne celui-ci.
        '''
        return self.prixPlace
    
    
        